﻿#pragma once
/**
@author 何炜
@date 2011/4/28
@brief .
*/
namespace GLL
{
	class ObjectManager;
	class ObjectComponent;

	/** 游戏物体.
	游戏里的物体，包括 灯光，摄像机，粒子，模型等 有[位置信息]的东西
	这个类和Ogre的SceneNode类功能是重合的，所以只作为一个借口存在，而不过多
	实现。具体实现，通过子类。*/
	class Object : public boost::enable_shared_from_this<Object>
	{
	public:
		enum Type
		{
			OT_None,
			OT_Light,
			OT_Camera,
			OT_Particle,
			OT_Mesh,
			OT_Helper,
		};
		typedef Combo2In1<int64, Type, Index> ID;

		static String ID2String(ID t);

		/**物体的标识符或基本属性.*/
		ID GetID(){return _id;}

		/**只读管理器.*/
		ObjectManager* GetMgr(){return _mgr;}

		/**有好的类型ID描述.*/
		virtual String StrID(){return ID2String(GetID());}

		/**析构.*/
		virtual ~Object();

	public:
		/**获取位置（物体空间属性）.
		数据子类保存，本类不需要保留信息*/
		virtual Position3Df GetPosition() = 0;

		/**设置位置（物体空间属性）.
		数据子类保存，本类不需要保留信息*/
		virtual void SetPosition(const Position3Df&) = 0;

		/**设置缩放（物体空间属性）.*/
		virtual void SetScale(const Size3Df&){}

		/**获取缩放（物体空间属性）.*/
		virtual Size3Df GetScale();

		/**设置旋转（物体空间属性）.
		@param 各个轴的旋转角度*/
		virtual void SetRotation(const Axis3Df&){}

		/**获取旋转（物体空间属性）.*/
		virtual Axis3Df GetRotation();

	public:
		/**组件.
		使用 GLL_NEW 创建
		@param ObjectComponent指针由Object类负责管理（delete）*/
		void AddCom(ObjectComponent*);

		/**.*/
		ObjectComponent* GetCom(const String& com_name);

		/**控制器.*/
		void RemoveCom(const String& com_name);

		/**.*/
		void ClearAllComs();

		/**.*/
		void NotifyAllComs();

		/**每帧更新.*/
		void UpdateAllComs(TimeMS);

	public:
		/**.*/
		virtual void _PreLoad(){}

		/**具体创建.
		可能会在线程中被调用。*/
		virtual void _DoLoad() = 0;

		/**载入完成后的操作.
		子类重载，需调用*/
		virtual void _PostLoad();

		/**具体删除.
		可能会在线程中被调用。*/
		virtual void _DoUnload() = 0;

		/**.*/
		virtual void _PostUnload(){}

	private:
		/**.*/
		void Update(TimeMS);

		/**.*/
		virtual bool OnUpdate(TimeMS){return false;}

		///ID.
		ID _id;

		///Manager.
		ObjectManager* _mgr;

		typedef GLL_HashMap<String, ObjectComponent*> ComVec;
		ComVec _coms;

	protected:
		/**构造. 
		通过Manager创建*/
		Object();

		//友元定义
		friend class ObjectManager;
	};

	typedef boost::shared_ptr<Object> ObjSrdPtr;
	typedef boost::weak_ptr<Object> ObjRefPtr;

};//GLL

namespace boost
{
	void checked_delete(GLL::Object*);
}
